<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import { type SendSmsReqVO, type SmsTemplate, sendSms } from '@/service/api';
import { $t } from '@/locales';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';

defineOptions({
  name: 'SmsTemplateSendModal'
});

interface Props {
  rowData?: SmsTemplate | null;
}

const props = defineProps<Props>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule, formRules } = useFormRules();

const formLoading = ref(false); // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用

const title = computed(() => {
  return $t('page.base.sms.template.sendTitle');
});

type Model = Pick<SendSmsReqVO, 'mobile' | 'params' | 'templateCode' | 'templateParams' | 'content'>;

const model: Model = reactive(createDefaultModel());

function createDefaultModel(): Model {
  return {
    mobile: '',
    templateCode: '',
    content: '',
    params: [],
    templateParams: new Map<string, string>()
  };
}

type RuleKey = Extract<keyof Model, 'mobile' | 'templateCode' | 'templateParams'>;

const rules: Record<RuleKey, App.Global.FormRule> = {
  mobile: formRules.phone[0],
  templateCode: defaultRequiredRule,
  templateParams: {}
};

async function handleInitModel() {
  model.mobile = '';
  model.templateParams = new Map<string, string>();
  if (props.rowData) {
    model.content = props.rowData.content;
    model.params = props.rowData.params;
    model.templateCode = props.rowData.code;

    rules.templateParams = props.rowData.params.reduce((obj, item) => {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-expect-error
      obj[item] = {
        required: true,
        message: `${$t('page.base.sms.template.paramsText')} ${item} ${$t('page.base.sms.template.form.paramNotNull')}`,
        trigger: 'blur'
      };
      return obj;
    }, {});
  }
}

async function handleSubmit() {
  await validate();

  formLoading.value = true;
  try {
    const data = model as SendSmsReqVO;
    const { data: logId } = await sendSms(data);
    if (logId) {
      window.$message?.success($t('page.base.sms.template.sendSmsSuccess') + logId);
      closeDrawer();
    }
  } finally {
    formLoading.value = false;
  }
}

function closeDrawer() {
  visible.value = false;
}

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    restoreValidation();
  }
});
</script>

<template>
  <NModal v-model:show="visible" :title="title" preset="card" :mask-closable="false" class="w-180">
    <NScrollbar class="max-h-200 pr-20px">
      <NForm ref="formRef" :model="model" :rules="rules" label-placement="left" label-width="auto">
        <NFormItem :label="$t('page.base.sms.template.mobile')" path="mobile">
          <NInput v-model:value="model.mobile" :placeholder="$t('page.base.sms.template.form.mobile')" />
        </NFormItem>
        <NFormItem :label="$t('page.base.sms.template.content')" path="content">
          <NInput
            v-model:value="model.content"
            :placeholder="$t('page.base.sms.template.form.content')"
            type="textarea"
          />
        </NFormItem>
        <NFormItem
          v-for="(item, index) in model.params"
          :key="index"
          :label="`${$t('page.base.sms.template.paramsText')} ` + '{' + item + '}'"
          :path="'templateParams.' + item"
        >
          <!-- @vue-expect-error -->
          <NInput
            v-model:value="model.templateParams[item]"
            :placeholder="
              `${$t('page.base.sms.template.form.pleaseEnter')} ` + item + ` ${$t('page.base.sms.template.paramsText')}`
            "
          />
        </NFormItem>
      </NForm>
    </NScrollbar>
    <template #footer>
      <NSpace justify="end" :size="16">
        <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
        <NButton type="primary" :disabled="formLoading" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
      </NSpace>
    </template>
  </NModal>
</template>
